<!--
 * @Date: 2024-07-30 15:27:24
 * @Author: LiSong
 * @LastEditors: LiSong
 * @LastEditTime: 2025-03-28 14:36:15
 * @Description: SQL配置面板
-->
<template>
  <div class="sql-config-panel">
    <div class="panel-header">
      <el-button size="default" type="primary" @click="analysisClick" :loading="sqlState.loading">SQL解析</el-button>
      <el-button size="default" type="default" @click="formatterClick">SQL美化</el-button>
      <!-- <el-button size="default" type="primary" @click="saveClick">保存</el-button> -->
    </div>
    <div class="panel-center">
      <AceCodeEditor
        ref="aceEditorRef"
        mode="sql"
        :border="true"
        :userWorker="false"
        v-model="analyseInfo.content"
      />
    </div>
  </div>
</template>

<script setup>
import { format } from 'sql-formatter';
import { XEUtils } from '@/utils'
import { VfMessage } from '@/utils/vf-utils'
import { ElMessageBox } from 'element-plus';
import { reactive, ref, inject, onBeforeMount } from 'vue';

import { AceCodeEditor } from '@/components/vf-editor'

import { useTableApi } from '@/api/api-table';

// 定义对外触发事件
const emits = defineEmits(['save', 'analysis', 'formatter']);

// 获取父级传递数据
const axiosConfig = inject('axiosConfig');
const getTableConfigData = inject('getTableConfigData')
const optionModel = getTableConfigData().optionModel

// 请求的API
const { analyseSQL } = useTableApi(axiosConfig.request);

onBeforeMount(() => {
  initAnalyseInfo();
});

const sqlState = reactive({
  loading: false
})
// 配置信息
const analyseInfo = reactive({
  // SQL内容
  content: '',
  // 字段数据
  fieldList: [],
  // 参数数据
  paramList: [],
});
/** 初始化解析数据 */
const initAnalyseInfo = () => {
  
  const { dataConfig } = optionModel;
  const copyDataConfig = XEUtils.clone(dataConfig, true)
  analyseInfo.content = copyDataConfig.sqlConfig.content;
  analyseInfo.fieldList = copyDataConfig.fieldList;
  analyseInfo.paramList = copyDataConfig.paramList;
};

const resetAnalyseInfo = () => {
  analyseInfo.content = '';
}

// ------ 功能按钮点击
const aceEditorRef = ref(null)
/** 保存按钮点击 */
const saveClick = () => {
  if (!validateContent()) return
  const result = {
    sqlConfig: { content: analyseInfo.content },
    fieldList: analyseInfo.fieldList,
    paramList: analyseInfo.paramList,
  };
  emits('save', XEUtils.clone(result, true));
};

/** 解析按钮点击 */
const analysisClick = async () => {
  if (!validateContent()) return
  let finalResult = { fieldList: [], paramList: [] }
  try {
    sqlState.loading = true
    // 获取解析的内容
    const { code, data, msg } = await analyseSQL(analyseInfo.content);
    if (code === 200) {
      // 封装解析后的数据
      finalResult = packageAnalyseInfo(data)
      if (XEUtils.isEmpty(analyseInfo.fieldList) && XEUtils.isEmpty(analyseInfo.paramList)) {
        emitsAnalysis(finalResult.fieldList, finalResult.paramList, true)
      } else {
        ElMessageBox.confirm(
          'SQL解析成功，存在字段或参数配置，请选择操作？',
          '提示',
          {
            type: 'warning',
            appendTo: '.data-source-dialog',
            customClass: 'vf-message-box-confirm',
            cancelButtonText: '覆盖',
            confirmButtonText: '追加',
            closeOnClickModal: false,
            closeOnPressEscape: false,
          }
        ).then(() => {
          emitsAnalysis(finalResult.fieldList, finalResult.paramList, false)
        }).catch(() => {
          emitsAnalysis(finalResult.fieldList, finalResult.paramList, true)
        })
      }
    } else {
      console.error('analysis sql error', msg)
      return;
    }
    sqlState.loading = false
  } catch (error) {
    sqlState.loading = false
    console.error('analysis sql error', error)
  }
};
/**
 * 向上触发analysis事件
 * 
 * @param fieldList 字段数据
 * @param paramList 参数数据
 * @param isCover 是否覆盖
 */
const emitsAnalysis = (fieldList, paramList, isCover=false) => {
  // 数据赋值
  analyseInfo.fieldList = fieldList
  analyseInfo.paramList = paramList
  // 向上触发方法
  emits('analysis', {
    fieldColumns: fieldList,
    paramColumns: paramList
  }, isCover);
}
/** 美化按钮点击 */
const formatterClick = () => {
  if (!validateContent()) return
  try {
    const formatContent = format(analyseInfo.content, {
      paramTypes: { custom: [{ regex: String.raw`\$\{\w+\}|#\{\w+\}|<\/\w+>|<(\w+)[^>]*\b\w+="([^"]*)"[^>]*>|<!--([\s\S]*?)-->` }] },
    });
    aceEditorRef.value.setValue(formatContent)
  } catch (error) {
    console.error('SQL美化失败，存在未指定占位符，请检查！', error)
  }
};
/** 验证输入SQL内容 */
const validateContent = () => {
  if (!analyseInfo.content) {
    VfMessage.warning('请输入需要解析的SQL语句！');
    return false;
  }
  return true
}

/**
 * 封装请求后端返回的字段数据
 * @param {Object} param { fieldList, paramList }
 */
const packageAnalyseInfo = ({ fieldList=[], paramList=[] }) => {
  const finalFieldList = fieldList.map(value => {
    return { field: value, title: value }
  })
  const fianlParamList = paramList.map(value => {
    return { field: value, title: value }
  })

  return {
    fieldList: XEUtils.clone(finalFieldList, true),
    paramList: XEUtils.clone(fianlParamList, true)
  }
}

defineExpose({
  saveClick,
  analysisClick,
  formatterClick,
  resetAnalyseInfo
});
</script>

<style lang="scss" scoped>
.sql-config-panel {
  height: 100%;
  padding: 0 8px;
  display: flex;
  flex-direction: column;
  .panel-header {
    // display: flex;
    height: 30px;
    margin: 0.6em 0;
    text-align: right;
    position: relative;
    // justify-content: end;
    // flex-direction: row;
    // align-items: center;
  }
  .panel-center {
    flex: 1;
    display: flex;
    flex-direction: column;
    margin-bottom: 6px;
  }
}
</style>
